<template>
	<div class="over-all-page">
		<div class="page-header">
			<div class="page-header-title">
				<img src="@/assets/images/logo.png" alt="" />
				<span>数智中台</span>
			</div>
			<div class="page-header-menu-list">
				<span class="page-header-menu-item" :class="{ active: activeMenu === 'teachingGraphData' }"
					>教学图谱全局</span
				>
			</div>
			<div class="other-content">
				<div class="go-btn" @click="goToAnalysisManageModule">进入分析管理</div>
			</div>
		</div>
		<div class="page-content">
			<div class="page-tabs-wrapper">
				<span
					class="tab-item"
					:class="{ active: activeTab === 'tree' }"
					@click="activeTab = 'tree'"
				>
					树图
				</span>
				<span
					class="tab-item"
					:class="{ active: activeTab === 'network' }"
					@click="activeTab = 'network'"
				>
					网图
				</span>
			</div>
			<div class="graph-search-wrapper">
				<el-input
					class="self-radius"
					v-model="searchNodeValue"
					placeholder="输入图谱节点名称搜索"
					:suffix-icon="Search"
					clearable
					@change="onSearchNodeHandle"
				/>
			</div>
			<el-tooltip
				ref="tooltipRef"
				:content="isOpenLeftMenu ? '收起课程列表' : '展开课程列表'"
				effect="customized"
				:show-after="0"
				:hide-after="200"
			>
				<div
					class="page-left-menu-btn"
					:class="{ active: isOpenLeftMenu }"
					@click="clickPageLeftMenuBtnHandle"
				>
					<el-icon>
						<DArrowRight v-if="!isOpenLeftMenu" />
						<DArrowLeft v-if="isOpenLeftMenu" />
					</el-icon>
				</div>
			</el-tooltip>
			<div v-show="isOpenLeftMenu" class="page-left-menu-wrapper">
				<div class="menu-title">课程列表</div>
				<div class="filter-wrapper">
					<div class="term-wrapper">
						<el-select v-model="filterCourseQuery.termCode" placeholder="选择学期">
							<el-option key="all" label="全部学期" value="all" />
							<el-option :key="1" :label="1" :value="1" />
						</el-select>
					</div>
					<div class="search-value-wrapper">
						<el-input
							v-model="filterCourseQuery.searchValue"
							placeholder="输入课程\老师名称搜索"
							:suffix-icon="Search"
						/>
					</div>
				</div>
				<div class="filter-statistics-wrapper">
					<span>课程</span>
					<span>（60）</span>
				</div>
				<div class="filter-result-wrapper">
					<div class="list-wrapper">
						<div
							class="list-item-wrapper"
							@mouseenter="
								handleCourseHover($event, {
									title: '办公自动化软件高级应用实践',
									teacher: '刘琦',
									classroom: '励志1班',
									term: '2024-2025学年第一学期',
									college: '计算机科学与技术学院'
								})
							"
							@mouseleave="handleCourseLeave"
						>
							<div class="title-wrapper">
								<span class="title-index">001</span>
								<span class="title-text">办公自动化软件高级应用实践</span>
							</div>
							<div class="other-wrapper">
								<span class="teacher">刘琦</span>
								<span class="divider">|</span>
								<span class="classroom">励志1班</span>
							</div>
						</div>
						<div
							class="list-item-wrapper"
							@mouseenter="
								handleCourseHover($event, {
									title: '办公自动化软件高级应用实践',
									teacher: '刘琦',
									classroom: '励志1班',
									term: '2024-2025学年第一学期',
									college: '计算机科学与技术学院'
								})
							"
							@mouseleave="handleCourseLeave"
						>
							<div class="title-wrapper">
								<span class="title-index">001</span>
								<span class="title-text">办公自动化软件高级应用实践</span>
							</div>
							<div class="other-wrapper">
								<span class="teacher">刘琦</span>
								<span class="divider">|</span>
								<span class="classroom">励志1班</span>
							</div>
						</div>
					</div>
				</div>
			</div>

			<!-- 详细信息弹框 - 在左侧菜单容器外部 -->
			<div v-show="courseDetail.visible" class="course-detail-popover" :style="courseDetail.style">
				<div class="detail-item">
					<span class="detail-title">{{ courseDetail.data.title }}</span>
				</div>
				<div class="detail-item">
					<span class="detail-label">教师名称：</span>
					<span class="detail-value">{{ courseDetail.data.teacher }}</span>
				</div>
				<div class="detail-item">
					<span class="detail-label">教学班级：</span>
					<span class="detail-value">{{ courseDetail.data.classroom }}</span>
				</div>
				<div class="detail-item">
					<span class="detail-label">授课学期：</span>
					<span class="detail-value">{{ courseDetail.data.term }}</span>
				</div>
				<div class="detail-item">
					<span class="detail-label">开课学院：</span>
					<span class="detail-value">{{ courseDetail.data.college }}</span>
				</div>
			</div>
			<div class="page-graph-wrapper">
				<NetworkGraph
					v-if="activeTab === 'network'"
					ref="networkGraphRef"
					:initial-data="networkGraphData"
					:relationStyleByType="relationStyleByType"
					:nodeStyleByType="nodeStyleByType"
					:isEdit="true"
					@node-click="handleNetworkNodeClick"
				></NetworkGraph>
				<TreeGraph
					v-else-if="activeTab === 'tree' && treeData"
					ref="treeGraphRef"
					:treeData="treeData"
					:isEdit="true"
					:themeConfig="themeConfig"
					@node-click="handleTreeNodeClick"
				></TreeGraph>
				<div class="toolbar-wrapper">
					<div class="grid-btn">
						<el-button
							><el-icon><Grid /></el-icon
						></el-button>
						<div class="grid-item-wrapper">
							<div class="grid-item">展开全部</div>
							<div class="grid-item">展开一级</div>
							<div class="grid-item">展开二级</div>
							<div class="grid-item">展开三级</div>
							<div class="grid-item">展开四级</div>
						</div>
					</div>
					<div class="center-btn" title="定位到中心">
						<el-button
							><el-icon><Aim /></el-icon
						></el-button>
					</div>
					<el-input-number v-model="zoomValue" :min="50" :max="150">
						<template #decrease-icon>
							<el-icon><ZoomOut /></el-icon>
						</template>
						<template #increase-icon>
							<el-icon><ZoomIn /></el-icon>
						</template>
						<template #suffix>
							<span>%</span>
						</template>
					</el-input-number>
				</div>
				<div class="type-group-wrapper">
					<div class="all type-group-item">
						<div class="type-group-title">全部</div>
					</div>
					<div class="type-group-item-wrapper">
						<div class="type-group-item">
							<div class="type-group-title">教学内容（3300）</div>
							<div class="type-sub-list">
								<span class="type-sub-item">
									<span class="type-sub-item-icon"></span>
									<span class="type-sub-item-text">知识点（2500）</span>
								</span>
								<span class="type-sub-item">
									<span class="type-sub-item-icon"></span>
									<span class="type-sub-item-text">理论联系实际（20）</span>
								</span>
								<span class="type-sub-item">
									<span class="type-sub-item-icon"></span>
									<span class="type-sub-item-text">实践应用（30）</span>
								</span>
							</div>
						</div>
						<div class="type-group-item">
							<div class="type-group-title">教学环节</div>
							<div class="type-sub-list">
								<span class="type-sub-item">
									<span class="type-sub-item-icon"></span>
									<span class="type-sub-item-text">学生作业（30）</span>
								</span>
								<span class="type-sub-item">
									<span class="type-sub-item-icon"></span>
									<span class="type-sub-item-text">教学活动（30）</span>
								</span>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>

		<!-- 节点详情弹框 -->
		<NodeInfoDialog
			:is-visible-node-info-dialog="isVisibleNodeInfoDialog"
			@closeNodeInfoDialog="closeNodeInfoDialog"
		></NodeInfoDialog>
	</div>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import {
	Search,
	CloseBold,
	DArrowRight,
	DArrowLeft,
	Close,
	Plus,
	VideoPlay,
	Grid,
	Aim,
	ZoomOut,
	ZoomIn
} from '@element-plus/icons-vue';
import NetworkGraph from '@/components/graph/NetworkGraph.vue';
import { NetworkNodeElType } from '@/components/graph/NetworkGraph.type';
import TreeGraph from '@/components/graph/TreeGraph.vue';
import { TreeNodeElType } from '@/components/graph/TreeGraph.type';
import { TooltipInstanceType } from '@/api/index';
import {
	MenuCourseDetailsElType,
	MenuCourseDetailsType,
	FilterCourseQueryType
} from './OverAll.type';
import NodeInfoDialog from '@/components/common/NodeInfoDialog.vue';

const activeMenu = ref<string>('teachingGraphData');
// 进入分析管理模块
const router = useRouter();
const goToAnalysisManageModule = () => {
	router.push({
		name: 'AnalysisTaskManage'
	});
};

/**
 * 课程列表
 */
const filterCourseQuery = ref<FilterCourseQueryType>({
	termCode: 'all',
	searchValue: ''
});
const isOpenLeftMenu = ref<boolean>(false);
const tooltipRef = ref<TooltipInstanceType>();
const clickPageLeftMenuBtnHandle = () => {
	isOpenLeftMenu.value = !isOpenLeftMenu.value;
	tooltipRef.value?.hide();
};

// 课程详情弹框
const courseDetail = ref<MenuCourseDetailsElType>({
	visible: false,
	style: {},
	data: {
		title: '',
		teacher: '',
		classroom: '',
		term: '',
		college: ''
	}
});
const handleCourseHover = (event: MouseEvent, data: MenuCourseDetailsType) => {
	const target = event.currentTarget as HTMLElement;
	const rect = target.getBoundingClientRect();

	courseDetail.value.visible = true;
	courseDetail.value.data = data;
	courseDetail.value.style = {
		position: 'fixed',
		left: `${rect.right + 30}px`,
		top: `${rect.top}px`,
		transform: 'translateY(0)'
	};
};
const handleCourseLeave = () => {
	courseDetail.value.visible = false;
};

// 获取课程详细信息
// 获取课堂详细信息

const activeTab = ref<string>('network');
const zoomValue = ref<number>(100);
/**
 * 教学图谱-网络图
 */
const networkGraphRef = ref<InstanceType<typeof NetworkGraph>>();
const networkGraphData = ref({
	nodes: [
		{ id: 'cs_foundation', label: '计算机科学基础', type: '核心领域' },
		{ id: 'discrete_math', label: '离散数学', type: '数学基础' },
		{ id: 'data_structures', label: '数据结构', type: '核心领域' },
		{ id: 'algorithms', label: '算法', type: '核心领域' },
		{ id: 'os', label: '操作系统', type: '核心领域' },
		{ id: 'computer_networks', label: '计算机网络', type: '核心领域' },
		{ id: 'databases', label: '数据库系统', type: '核心领域' },
		{ id: 'python', label: 'Python语言', type: '编程语言' },
		{ id: 'java', label: 'Java语言', type: '编程语言' },
		{ id: 'c_plus_plus', label: 'C++语言', type: '编程语言' },
		{ id: 'array_list', label: '数组/链表', type: '具体技术/概念' },
		{ id: 'tree_graph', label: '树/图', type: '具体技术/概念' },
		{ id: 'sorting_searching', label: '排序/查找算法', type: '具体技术/概念' },
		{ id: 'tcp_ip', label: 'TCP/IP协议', type: '具体技术/概念' },
		{ id: 'sql', label: 'SQL', type: '具体技术/概念' },
		{ id: 'oop', label: '面向对象编程', type: '具体技术/概念' },
		{ id: 'ai', label: '人工智能', type: '应用领域' },
		{ id: 'web_dev', label: 'Web开发', type: '应用领域' },
		{ id: 'software_engineering', label: '软件工程', type: '应用领域' }
	],
	links: [
		{ source: 'cs_foundation', target: 'data_structures', label: '包含' },
		{ source: 'cs_foundation', target: 'algorithms', label: '包含' },
		{ source: 'cs_foundation', target: 'os', label: '包含' },
		{
			source: 'discrete_math',
			target: 'data_structures',
			label: '是...的基础'
		},
		{ source: 'discrete_math', target: 'algorithms', label: '是...的基础' },
		{
			source: 'data_structures',
			target: 'algorithms',
			label: '是...的基础'
		},
		{ source: 'data_structures', target: 'array_list', label: '包含' },
		{ source: 'data_structures', target: 'tree_graph', label: '包含' },
		{ source: 'algorithms', target: 'sorting_searching', label: '包含' },
		{ source: 'algorithms', target: 'ai', label: '应用于' },
		{ source: 'os', target: 'computer_networks', label: '是...的基础' },
		{ source: 'computer_networks', target: 'tcp_ip', label: '包含' },
		{ source: 'databases', target: 'sql', label: '使用' },
		{ source: 'databases', target: 'web_dev', label: '应用于' },
		{ source: 'python', target: 'data_structures', label: '用于实现' },
		{ source: 'python', target: 'ai', label: '用于实现' },
		{ source: 'python', target: 'web_dev', label: '用于实现' },
		{ source: 'c_plus_plus', target: 'os', label: '用于实现' },
		{ source: 'java', target: 'oop', label: '是...的范例' },
		{ source: 'java', target: 'web_dev', label: '用于实现' },
		{ source: 'oop', target: 'software_engineering', label: '是...的基础' }
	]
});
const relationStyleByType = ref([
	{ label: '包含', isHierarchy: true },
	{ label: '是...的基础', isHierarchy: true },
	{ label: '应用于', isHierarchy: false },
	{ label: '用于实现', isHierarchy: true },
	{ label: '使用', isHierarchy: false },
	{ label: '是...的范例', isHierarchy: false }
]);
const nodeStyleByType = ref([
	{ type: '核心领域', color: '#1f77b4', size: 50, textPosition: 'center' },
	{ type: '数学基础', color: '#d62728', size: 40, textPosition: 'center' },
	{ type: '编程语言', color: '#2ca02c', size: 40, textPosition: 'bottom' },
	{
		type: '具体技术/概念',
		color: '#ff7f0e',
		size: 30,
		textPosition: 'bottom'
	},
	{ type: '应用领域', color: '#9467bd', size: 45, textPosition: 'bottom' }
]);
// 网络图节点被点击
const handleNetworkNodeClick = (node: NetworkNodeElType) => {
	console.log(node);
};

/**
 * 教学图谱-树图
 */
const treeGraphRef = ref<InstanceType<typeof TreeGraph>>();
const treeData = ref({
	nodes: [
		{ id: 'root', label: '根节点', type: '核心领域' },
		{ id: 'child1', label: '子节点1', type: '数学基础' },
		{ id: 'child2', label: '子节点2', type: '编程语言' }
	],
	links: [
		{ source: 'root', target: 'child1', label: '关联', isHierarchy: false },
		{ source: 'root', target: 'child2', label: '包含', isHierarchy: true }
	]
});
const themeConfig = ref({
	// 层级样式配置（colorMode="level" 时生效）
	root: {
		fillColor: '#e53e3e'
	},
	second: {
		fillColor: '#38a169'
	},
	node: {
		fillColor: '#3182ce'
	},
	// 类型样式配置（colorMode="type" 时生效）
	typeColors: {
		核心领域: {
			fillColor: '#ff6600'
		},
		数学基础: {
			fillColor: 'blue'
		},
		编程语言: {
			fillColor: 'green'
		},
		'具体技术/概念': {
			fillColor: '#333'
		},
		应用领域: {
			fillColor: '#999'
		},
		测试类型: {
			fillColor: '#eee'
		},
		已编辑类型: {
			fillColor: 'red'
		}
	}
});

// 树图节点被点击
const isVisibleNodeInfoDialog = ref(false);
const handleTreeNodeClick = (node: TreeNodeElType) => {
	console.log(node);
	isVisibleNodeInfoDialog.value = true;
};
const closeNodeInfoDialog = () => {
	isVisibleNodeInfoDialog.value = false;
};

// 搜索节点
const searchNodeValue = ref('');
const onSearchNodeHandle = () => {
	if (activeTab.value === 'tree' && searchNodeValue.value) {
		treeGraphRef.value?.highlightNodeByNodeName(searchNodeValue.value);
	}
	if (activeTab.value === 'network' && searchNodeValue.value) {
		networkGraphRef.value?.highlightNodesByLabelWithRelations(searchNodeValue.value);
	}
};
</script>
<style scoped lang="scss">
.over-all-page {
	width: 100%;
	height: 100%;
}

.page-header {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: space-between;
	height: 7.2rem;
	padding-left: 3rem;
	padding-right: 3rem;
	background: url('@/assets/images/header-bg.png') no-repeat center top/100% 100%;

	.page-header-title {
		display: flex;
		align-items: baseline;
		position: relative;
		top: 2px;
		font-family: 'douyinbold';
		font-size: $font-size-large-5;
		color: #fff;

		img {
			margin-right: 1rem;
		}
	}

	.page-header-menu-list {
		position: absolute;
		top: 0;
		left: 50%;
		display: flex;
		align-items: center;
		height: 100%;
		transform: translateX(-50%);

		.page-header-menu-item {
			display: flex;
			align-items: center;
			height: 100%;
			margin-left: 6rem;
			padding: 1rem 2rem;
			font-size: $font-size-large-1;
			color: #fff;
			cursor: pointer;

			&:hover {
				background-color: rgba(color.adjust($color-brand, $lightness: -30%), 0.5);
			}
		}

		.page-header-menu-item:first-child {
			margin-left: 0;
		}

		.page-header-menu-item.active {
			color: #fff;
			background-color: rgba(color.adjust($color-brand, $lightness: -30%), 0.5);
		}
	}

	.other-content {
		display: flex;
		align-items: center;

		.go-btn {
			padding: 0.6rem 1.2rem;
			font-size: $font-size-large-1;
			color: $text-color-regular;
			background: rgba(255, 255, 255, 0.5);
			border-radius: 6px;
			text-decoration: underline;
			cursor: pointer;
		}
	}
}

.page-content {
	position: relative;
	height: calc(100% - 7.2rem);
	padding: 2rem;

	.graph-search-wrapper {
		position: absolute;
		right: 2rem;
		top: 2rem;
	}

	.page-left-menu-btn {
		position: absolute;
		left: 0;
		top: 2rem;
		display: flex;
		align-items: center;
		justify-content: center;
		width: 4rem;
		height: 4rem;
		font-size: 2.8rem;
		border-top-right-radius: 50%;
		border-bottom-right-radius: 50%;
		background-color: #ffffff;
		box-shadow: 0px 2px 4px 0px rgba(31, 15, 93, 0.2);
		cursor: pointer;

		&.active {
			left: 32rem;
		}

		&:hover {
			background-color: color.adjust($color-brand, $lightness: 12%);
			color: #fff;
		}
	}

	.page-left-menu-wrapper {
		display: flex;
		flex-direction: column;
		position: absolute;
		left: 2rem;
		top: 2rem;
		bottom: 2rem;
		width: 30rem;
		padding: 2rem;
		background-color: #fdfcff;
		border-top-left-radius: 4px;
		border-bottom-left-radius: 4px;
		border-bottom-right-radius: 4px;
		box-shadow: 0px 0px 8px 0px rgba(26, 60, 207, 0.18);
		z-index: 10;
		.menu-title {
			margin-bottom: 1rem;
			font-size: $font-size-large-1;
			color: color.adjust($color_brand, $lightness: -50%);
		}

		.filter-wrapper {
			display: flex;
			margin-bottom: 1rem;

			.term-wrapper {
				:deep(.el-select__wrapper) {
					height: 32px;
					width: 12rem;
					border-top-left-radius: 16px;
					border-bottom-left-radius: 16px;
					border-top-right-radius: 0;
					border-bottom-right-radius: 0;
					border: 1px solid $border-color-primary;
					box-shadow: none;
				}
			}

			.search-value-wrapper {
				:deep(.el-input__wrapper) {
					height: 32px;
					border-top-right-radius: 16px;
					border-bottom-right-radius: 16px;
					border-top-left-radius: 0;
					border-bottom-left-radius: 0;
					border: 1px solid $border-color-primary;
					border-left: none;
					box-shadow: none;
				}
			}
		}

		.filter-statistics-wrapper {
			display: flex;
			align-items: flex-start;
			color: $text-color-secondary;
			margin-bottom: 1rem;
		}

		.filter-result-wrapper {
			flex: 1;
			min-height: 0;
			overflow: auto;

			.list-wrapper {
				.list-item-wrapper {
					position: relative;
					margin-bottom: 1rem;
					padding: 1rem;
					border-radius: 4px;
					border-bottom: 1px solid $border-color-primary;
					cursor: pointer;
					transition: all 0.3s ease;

					&:hover {
						background-color: $bg-block-color-brand;
						border-bottom-color: transparent;
					}
					&:last-child {
						margin-bottom: 0;
					}
					&:active {
						background-color: $bg-block-color-brand;
						border-bottom-color: transparent;
					}

					.title-wrapper {
						display: flex;
						align-items: baseline;
					}

					.title-index {
						display: block;
						width: 3.5rem;
						font-size: $font-size-small-2;
						color: $text-color-secondary;
						overflow: hidden;
						white-space: nowrap;
						text-overflow: ellipsis;
					}

					.title-text {
						font-size: $font-size-base;
						color: $text-color-regular;
						overflow: hidden;
						white-space: nowrap;
						text-overflow: ellipsis;
					}

					.other-wrapper {
						display: flex;
						align-items: baseline;
						padding-left: 3.5rem;
						padding-top: 0.5rem;
						font-size: $font-size-small-1;
						color: $text-color-secondary;
					}

					.teacher {
						font-size: $font-size-small-1;
						color: $text-color-secondary;
						padding-right: 1rem;
					}

					.divider {
						position: relative;
						top: -1px;
						font-size: 1.2rem;
					}

					.classroom {
						font-size: $font-size-small-1;
						color: $text-color-secondary;
						margin-left: 1rem;
					}
				}
			}
		}
	}

	// 课程详情弹框（位于左侧菜单外部）
	.course-detail-popover {
		min-width: 28rem;
		max-width: 35rem;
		background: #ffffff;
		box-shadow: 0px 0px 8px 0px rgba(26, 60, 207, 0.18);
		border-radius: 4px;
		padding: 1.5rem;
		z-index: 1000;
		&::before {
			content: '';
			position: absolute;
			left: -1rem;
			top: 4rem;
			width: 0;
			height: 0;
			border-left: 0.5rem solid transparent;
			border-right: 0.5rem solid #ffffff;
			border-bottom: 0.5rem solid transparent;
			border-top: 0.5rem solid transparent;
		}

		.detail-item {
			display: flex;
			align-items: baseline;
			margin-bottom: 1rem;
			line-height: 1.6;

			&:last-child {
				margin-bottom: 0;
			}
			.detail-title {
				font-size: $font-size-base;
				color: $text-color-primary;
			}

			.detail-label {
				flex-shrink: 0;
				min-width: 7rem;
				font-size: $font-size-small-1;
				color: $text-color-secondary;
				font-weight: 500;
			}

			.detail-value {
				flex: 1;
				font-size: $font-size-small-1;
				color: $text-color-regular;
				word-break: break-all;
			}
		}
	}

	.page-graph-wrapper {
		position: relative;
		height: calc(100% - 5rem);

		.type-group-wrapper {
			bottom: 3.8rem;
			right: 0;
		}
	}
}
</style>
